package com.camel.core.config;

import com.camel.core.enums.BaseEnum;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
import com.fasterxml.jackson.databind.node.IntNode;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import org.springframework.util.ObjectUtils;

import java.io.IOException;

/**
 * @author Administrator
 */
@NoArgsConstructor
@AllArgsConstructor
public class RequestEnumJsonDeserialize extends JsonDeserializer<BaseEnum> implements ContextualDeserializer {

    private JavaType type;

    @Override
    public BaseEnum deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        if (this.type == null || !this.type.isEnumType()) {
            return null;
        }
        ObjectCodec oc = p.getCodec();
        JsonNode node = oc.readTree(p);

        if (node == null) {
            return null;
        }
        if (!(node instanceof IntNode) && !(node.get("code") instanceof IntNode)) {
            return null;
        }

        Object[] enumConstants = this.type.getRawClass().getEnumConstants();
        for (Object e : enumConstants) {
            if (e instanceof BaseEnum) {
                BaseEnum ie = (BaseEnum) e;
                if (ie.getValue().equals(node.asInt()) || !ObjectUtils.isEmpty(node.get("code")) && ie.getValue().equals(node.get("code").asInt())) {
                    return ie;
                }
            }
        }
        return null;
    }

    @Override
    public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) {
        JavaType type = ctxt.getContextualType() != null
                ? ctxt.getContextualType()
                : property.getMember().getType();
        return new RequestEnumJsonDeserialize(type);
    }
}